﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Modularity;
using Volo.Abp.TenantManagement.EntityFrameworkCore;
using Volo.Abp.TenantManagement;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.Autofac;
using Volo.Abp.Swashbuckle;
using AbpVnext_Module.Interceptor;
using System.Reflection;
using Volo.Abp.DynamicProxy;
using AbpVnext_Module.Controllers;
using AbpVnext_Module.ExceptionFillter;
using System.Net;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.Identity;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Account.Web;
using Microsoft.OpenApi.Models;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.AuditLogging;
using Volo.Abp.SettingManagement;
using Volo.Abp.MultiTenancy;
using Volo.Abp.FeatureManagement;
using Volo.Abp.Auditing;
using Volo.Abp.VirtualFileSystem;
using Microsoft.Extensions.Hosting.Internal;
using Microsoft.Extensions.FileProviders;
using Ebusiness_Domain.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Validation.Localization;
//using EmbeddedResources_Test;
using Volo.Abp.OpenIddict;
using Volo.Abp.Data;

namespace AbpVnext__Comon
{
    /// <summary>
    /// 所有的项目，抽象成AbpModule
    /// 方便使用和维护。
    ///  项目服务隔离 ，好处：独立维护
    /// </summary>
    [DependsOn(
        typeof(AbpAspNetCoreMvcModule),
                typeof(AbpAutofacModule),
        typeof(AbpSwashbuckleModule),
        typeof(EntityFrameWorkMoudule),
        typeof(ApplicationMoudule),
        typeof(HttpApiMoudule)
        //, typeof(AbpAuthorizationModule)  //身份授权模块

        //配置应用账户模块
        , typeof(AbpAccountWebModule)

        //配置多租户切换模块
        , typeof(AbpAspNetCoreMultiTenancyModule)
        , typeof(AbpAspNetCoreSerilogModule)   //日志模块
        , typeof(AbpVirtualFileSystemModule)  //集成虚拟文件系统
        //, typeof(AbpLocalizationModule)  //集成本地化模块

        //, typeof(EmbeddedResourcesMoudule) //测试打包程序包含dll文件
        //, typeof(AbpOpenIddictAspNetCoreModule) //分布式认证模块
        //, typeof(AbpAccountWebOpenIddictModule) //分布式认证模块 AbpAccountWebOpenIddictModule 依赖AbpOpenIddictAspNetCoreModule 模块
        )]
    public class HostMoudule : AbpModule
    {

        #region 配置动态代理
        /// <summary>
        /// 添加动态代理 , 拦截器
        /// </summary>
        /// <param name="context"></param>
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            //base.PreConfigureServices(context);
            //注册拦截器
            //判断(类/方法)上是否有LogEnable
            context.Services.OnRegistered(option =>
            {
                //if (option.ImplementationType.FullName.EndsWith("Controller"))
                //{

                //}
                if (ShuouldIntercept(option.ImplementationType))
                {
                    //开始拦截
                    option.Interceptors.Add<LoggerInterceptor>();
                }
            });
        }

        /// <summary>
        /// 筛选要拦截的类
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private static bool ShuouldIntercept(Type type)
        {
            //if (type.IsAbstract)
            //{

            //}
            //if (typeof(Product) == type)
            //{

            //}
            return !DynamicProxyIgnoreTypes.Contains(type)
                && (type.IsDefined(typeof(LogEnable), true) || AnyMethodHasLogEnableAttribute(type));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static bool AnyMethodHasLogEnableAttribute(Type type)
        {
            //return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(x => x.IsDefined(typeof(LogEnable), true));
            var data = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(x => x.IsDefined(typeof(LogEnable), true)).ToList();
            //if (data.Count() > 0)
            //{

            //}
            return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(HasLogEnableAttribute);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static bool HasLogEnableAttribute(MemberInfo memberInfo)
        {
            return memberInfo.IsDefined(typeof(LogEnable), true);
        }
        #endregion

        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="context"></param>
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            #region 默认配置
            {
                //// Add services to the container.
                //IServiceCollection Services = context.Services;
                //Services.AddControllers(option =>
                //{
                //    //全局取消默认token校验
                //    //option.Filters.Add(new IgnoreAntiforgeryTokenAttribute());
                //});
                //// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
                //Services.AddEndpointsApiExplorer();
                //Services.AddSwaggerGen();
                //////设置  Cookie 身份认证
                ////Services.AddAuthentication().AddCookie();
                //////设置权限
                ////Services.AddAuthorization();

                ////配置AspNetCoreMvc模块
                //Configure<AbpAspNetCoreMvcOptions>(option =>
                //{

                //});

                //Services.AddSwaggerGen();
            }
            #endregion

            IServiceCollection services = context.Services;
            IConfiguration configuration = services.GetConfiguration();
            // Add services to the container.
            //配置自定义控制器
            ConfigurControllers(context, configuration);
            //配置日志工厂模式
            ConfigLogFactory(context, configuration);
            //配置身份认证模块
            ConfigureAuthentication(context, configuration);
            //配置Swagger
            ConfigureSwaggerServices(context, configuration);
            //配置api自动控制器
            ConfigureConventionalControllers();
            //配置异常处理模块
            ConfigurException(context);
            //配置多租户模块
            ConfigureMultiTenancy();
            //配置虚拟文件系统
            ConfigureVirtualFileSystem(context);
            //配置审计日志模块
            //ConfigAuditing();
            //配置本地化
            //ConfigureLocalization();
            //配置应用模块表后缀名
            ConfigurModelProix();
            ////取消所有的权限校验
            //context.Services.AddAlwaysAllowAuthorization();
        }

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            #region 默认配置
            {
                //IWebHostEnvironment webHostEnvironment = context.GetEnvironment();
                //IApplicationBuilder applicationBuilder = context.GetApplicationBuilder();

                //// Configure the HTTP request pipeline.
                //if (webHostEnvironment.IsDevelopment())
                //{
                //    applicationBuilder.UseSwagger();
                //    applicationBuilder.UseSwaggerUI();
                //}
                ////添加静态资源中间件
                //applicationBuilder.UseStaticFiles();
                ////使用路由
                //applicationBuilder.UseRouting();
                ////使用路由中间件
                ////applicationBuilder.UseHttpsRedirection();
                ////身份验证中间件
                ////applicationBuilder.UseAuthentication();
                ////授权
                //applicationBuilder.UseAuthorization();

                ////applicationBuilder.MapControllers();
                //applicationBuilder.UseConfiguredEndpoints();
            }
            #endregion

            IApplicationBuilder app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();
            // Configure the HTTP request pipeline.

            //if (env.IsDevelopment())
            //{
            app.UseSwagger();
            //app.UseSwaggerUI();
            app.UseAbpSwaggerUI(option => option.SwaggerEndpoint("/swagger/v3/swagger.json", $"{typeof(HostMoudule).Assembly.GetName().Name} Api"));
            //}

            // 启用本地化中间件
            app.UseAbpRequestLocalization();
            //var t = Path.Combine(Directory.GetCurrentDirectory(), "File");
            //var w = AppDomain.CurrentDomain.BaseDirectory;

            #region
            //添加静态资源中间件
            //app.UseStaticFiles(new StaticFileOptions
            //{
            //    FileProvider = new PhysicalFileProvider(
            //           Path.Combine(Directory.GetCurrentDirectory(), "File")),
            //    RequestPath = "/StaticFiles"
            //});
            #endregion
            app.UseStaticFiles();
            //使用路由中间件
            app.UseRouting();
            #region
            //日志测试
            //var xx = context.GetLoggerFactory();
            //var w = xx.CreateLogger<HostBuilder>();
            //for (var i = 0; i < 100000; i++)
            //{
            //    w.LogInformation("xxxxxxxxxxxx//////");
            //    w.LogError("xxxxxxxxxxxx/////");
            //}

            //app.Use(next =>
            //{
            //    return async x =>
            //    {
            //        bool? bl = x.User.Identity.IsAuthenticated;
            //        var path = x.Request.Path.Value;
            //        // 2、给下一个中间件
            //        await next(x);
            //        //x.Response.StatusCode = 401; //如果授权失败 可以通过中间件修改状态码
            //    };
            //});
            #endregion
            //身份验证中间件
            app.UseAuthentication();
            #region 
            //使用中间件
            //app.UseAuthencation();
            //app.Use(next =>
            //{
            //    return async x =>
            //    {
            //        bool? bl = x.User.Identity.IsAuthenticated;
            //        var path = x.Request.Path.Value;
            //        // 2、给下一个中间件
            //        await next(x);
            //    };
            //});

            //使用多租户中间件
            //多租户中间件要放在用户鉴权中间件之前 否则会出现多租户鉴权失败
            #endregion
            app.UseMultiTenancy();
            //授权中间件
            app.UseAuthorization();
            //审计日志中间件
            //app.UseAuditing();
            #region
            //使用中间件
            //app.UseAuthenzetion();
            //app.Use(next =>
            //{
            //    return async x =>
            //    {
            //        bool bl = x.User.Identity.IsAuthenticated;
            //        var path = x.Request.Path.Value;
            //        // 2、给下一个中间件
            //        await next(x);
            //    };
            //});
            //app.MapControllers();
            #endregion
            app.UseConfiguredEndpoints(); //执行Abp Action

            //添加OpenIddict ，对应的微服务信息和客户端信息
            //context.ServiceProvider
            //    .GetRequiredService<IDataSeeder>()
            //    .SeedAsync().Wait();
            //context.ServiceProvider.GetRequiredService<IDataSeeder>().SeedAsync().Wait();
        }

        /// <summary>
        /// 配置自定义控制器
        /// </summary>
        public void ConfigurControllers(ServiceConfigurationContext context, IConfiguration configuration)
        {
            //配置自定义过滤器
            context.Services.AddControllers(option =>
            {
                //添加自定义过滤器
                option.Filters.Add<CustomExceptionFilter>();
                //全局取消默认token校验 忽略xss攻击
                option.Filters.Add(new IgnoreAntiforgeryTokenAttribute());
            });
            //servicesout configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            context.Services.AddEndpointsApiExplorer();
        }

        /// <summary>
        /// 配置日志工厂模式
        /// </summary>
        public void ConfigLogFactory(ServiceConfigurationContext context, IConfiguration configuration)
        {
            ////配置日志工厂
            //context.Services.AddLogging(x =>
            //{
            //    x.AddConfiguration(configuration.GetSection("Logging"));
            //    x.AddLog4Net("log4Net.config");
            //    x.AddConsole();
            //});
        }

        /// <summary>
        /// 配置异常处理模块
        /// </summary>
        public void ConfigurException(ServiceConfigurationContext context)
        {
            ////配置Api控制器异常
            Configure<AbpExceptionHandlingOptions>(oprion =>
            {
                //显示具体异常信息
                oprion.SendExceptionsDetailsToClients = false;
                //不显示异常堆栈
                oprion.SendStackTraceToClients = false;
            });

            //配置Api控制器异常响应状态码
            Configure<AbpExceptionHttpStatusCodeOptions>(option =>
            {
                //异常编码与响应编码映射
                option.Map("-1", HttpStatusCode.TooManyRequests);
                option.Map("2", HttpStatusCode.InternalServerError);
                option.Map("3", HttpStatusCode.NotImplemented);
                option.Map("4", HttpStatusCode.BadRequest);
                option.Map("xxx", HttpStatusCode.OK);
            });
        }

        /// <summary>
        /// 配置多租户模块
        /// </summary>
        public void ConfigureMultiTenancy()
        {
            Configure<AbpMultiTenancyOptions>(option =>
            {
                option.IsEnabled = true;
            });
        }

        /// <summary>
        /// 配置api自动控制器
        /// </summary>
        public void ConfigureConventionalControllers()
        {
            //配置AspNetCoreMvc模块
            Configure<AbpAspNetCoreMvcOptions>(option =>
            {

                //自动APi控制器
                //加载项目程序集  
                option.ConventionalControllers.Create(typeof(ApplicationMoudule).Assembly, option =>
                {
                    //修改自动api控制器的根路径(abp)  //配置改造
                    option.RootPath = "projects";
                });
                //忽略手动api控制器
                //option.ControllersToRemove.Add(typeof(ProductImageController));

                //开启全局自动验证dto ，验证参数是否符合规范  默认配置为true
                //关闭之后，可以使用IValidationEnabled接口类局部开启
                //局部验证 -> 全局验证 -> 自动api验证或者手动api验证（默认）
                option.AutoModelValidation = false;
            });
        }

        /// <summary>
        /// 配置身份认证模块
        /// </summary>
        /// <param name="context"></param>
        public void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
        {
            #region 身份验证模块
            //设置  Cookie 身份认证
            //在 ASP.NET Core 中，当你使用 AddAuthentication().AddCookie() 添加 Cookie 认证时，并没有直接指定一个具体的加密算法用于加密 Cookie 中的数据。
            //相反，ASP.NET Core 使用了 .NET Core 提供的 Data Protection API 来处理敏感数据的保护，这包括加密和签名。
            //Data Protection API 使用的是一种基于密钥的加密机制，但具体的加密算法（如 AES、RSA 等）是抽象化的，并且可能会随着.NET Core 版本的更新而更改。
            //Data Protection API 的目标是提供一个易于使用的 API，允许开发人员加密和验证数据，而无需深入了解底层加密机制。
            //context.Services.AddAuthentication(option =>
            //{
            //    //配置jwt认证方案
            //    //var deault = option.DefaultAuthenticateScheme;
            //    //var defalut = option.DefaultChallengeScheme;
            //}).AddCookie(option =>
            //{
            //    //option.Cookie.Name = "test";
            //    //option.ExpireTimeSpan = TimeSpan.FromMinutes(60);
            //});

            //微软默认身份认证 cookie认证 
            //应用身份认证模块volo..Identity.AspNetCore 、Volo.Abp.Account.Web 集成了AddAuthentication 身份认证
            // context.Services.AddAuthentication().AddCookie();

            //配置 jwt 身份认证
            //string? jwtSecurity = configuration.GetSection("configuration").Value;
            //services.AddAuthentication(option =>
            //{
            //    //配置jwt认证方案
            //    var deault = option.DefaultAuthenticateScheme;
            //    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            //    var defalut = option.DefaultChallengeScheme;
            //    option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            //}).AddJwtBearer(option =>
            //{
            //    //配置token认证方式  设置哪些字段为true 代表验证哪些字段
            //    option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
            //    {
            //        ValidateIssuer = true, //认证签发者 。生产token系统
            //        ValidateAudience = true,//认证受用者 erp系统
            //                                //ValidateLifetime = true,//认证生成token时间
            //        ValidateIssuerSigningKey = true,
            //        ValidIssuer = "jwt", //认证签发者 。生产token系统
            //        ValidAudience = "BasicModuleWebApiJWTAuthorization", //认证受用者 erp系统
            //        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecurity ?? "R2XMnd6TQdYRUmR0cCfL9fk651Fb3kDI")) //认证生成token密钥
            //    };
            //});

            //设置权限
            //Volo.Abp.Authorization 集成了授权模块 
            //context.Services.AddAuthorization(); 

            //微软自带身份认证
            //AddIdentity方法的参数类型指定AppUser类和IdentityRole类
            //AddEntityFrameworkStores方法指定Identity使用EF Core作为存储和项目中使用AppIdentityContext作为DB Context
            //context.Services.AddIdentity<Microsoft.AspNetCore.Identity.IdentityUser, Microsoft.AspNetCore.Identity.IdentityRole>()
            //    .AddEntityFrameworkStores<AppDbContext>().AddDefaultTokenProviders();
            #endregion
        }

        /// <summary>
        /// 配置Swagger
        /// </summary>
        /// <param name="context"></param>
        /// <param name="configuration"></param>
        public void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
        {
            #region swagger 模块
            //不带身份验证注册
            //services.AddSwaggerGen();
            //带身份验证注册
            //services.AddAbpSwaggerGen(option =>
            //{
            //    //添加token验证
            //    option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            //    {
            //        Description = "请输入token,格式为 Bearer xxxxxxxx",
            //        Name = "Authorization", //标头名
            //        In = ParameterLocation.Header,  //表示头部
            //        Type = SecuritySchemeType.ApiKey,
            //        BearerFormat = "JWT",  //token
            //        Scheme = "Bearer"
            //    });
            //    //添加验证条件
            //    option.AddSecurityRequirement(new OpenApiSecurityRequirement
            //    {
            //          {
            //            //Id = "Bearer" 表示引用的安全方案的 ID 是 "Bearer"，这个 ID 必须与之前通过 AddSecurityDefinition 定义的安全方案一致。
            //            //这部分代码的作用是告诉 Swagger 使用之前定义的 "Bearer" 安全方案。
            //            new OpenApiSecurityScheme{ Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id ="Bearer" } },
            //            new string[]{ }//不设权限
            //          }
            //    });
            //    option.SwaggerDoc("v3",
            //        new OpenApiInfo
            //        {
            //            Title = typeof(HostMoudule).Assembly.GetName().Name + "哈哈哈", //组名字，右上角可以选择
            //            Version = "v1",//版本
            //            Description = $"接口文档说明，放这里 ",
            //            Contact = new OpenApiContact()
            //            {
            //                Name = "zhangsan",//名字
            //                Email = "xxx@qq.com",//邮箱
            //                Url = null
            //            }//通常这里都是放联系，地址的，一般不用
            //        });
            //    //显示Abp自动api接口
            //    option.DocInclusionPredicate((x, y) => true);
            //    //option.CustomSchemaIds(ty => ty.FullName);
            //    // true : 设置控制器层注释，对控制器中方法的注释的显示
            //    // xml文档绝对路径,"WebApplication2"为项目名，表示读取该项目的xml文件
            //    //将上面代码放进去会报错，因为我们设置了xml文档地址：开启方法》右键项目》属性》生成》输出》打开“生成包含api的文档的文件”之后就可以直接运行了。
            //    var x = typeof(HostMoudule).Assembly.GetName().Name;
            //    var file = Path.Combine(AppContext.BaseDirectory, $"{x}.xml");
            //    // xml文档绝对路径
            //    //var path = Path.Combine(AppContext.BaseDirectory, file);
            //    option.IncludeXmlComments(file, true);
            //    //加载别的程序集文档文件
            //    option.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(HttpApiMoudule).Assembly.GetName().Name}.xml"), true);
            //    // 对方法名的名称进行排序，首字母顺序。
            //    option.OrderActionsBy(o => o.RelativePath);
            //});

            //IConfiguration configuration = services.GetConfiguration();
            //带身份验证注册
            context.Services.AddAbpSwaggerGenWithOAuth(configuration["AuthServer:Authority"],
                new Dictionary<string, string>()
                {
                    { "api" ,$"{typeof(HostBuilder).Assembly.GetName().Name}" }
                }
                , option =>
                {
                    option.SwaggerDoc("v3",
                       new OpenApiInfo
                       {
                           Title = typeof(HostMoudule).Assembly.GetName().Name + "哈哈哈", //组名字，右上角可以选择
                           Version = "v1",//版本
                           Description = $"接口文档说明，放这里 ",
                           Contact = new OpenApiContact()
                           {
                               Name = "zhangsan",//名字
                               Email = "xxx@qq.com",//邮箱
                               Url = null
                           }//通常这里都是放联系，地址的，一般不用
                       });
                    //显示Abp自动api接口
                    option.DocInclusionPredicate((x, y) => true);
                    option.CustomSchemaIds(ty => ty.FullName);
                    // true : 设置控制器层注释，对控制器中方法的注释的显示
                    option.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(HostMoudule).Assembly.GetName().Name}.xml"), true);
                    //加载别的程序集文档文件
                    option.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(HttpApiMoudule).Assembly.GetName().Name}.xml"), true);
                    // 对方法名的名称进行排序，首字母顺序。
                    //option.OrderActionsBy(o => o.RelativePath);
                });
            #endregion
        }

        /// <summary>
        /// 配置审计日志模块
        /// </summary>
        private void ConfigAuditing()
        {
            #region 应用审计模块原理
            {
                //审计日志执行的原理
                //AuditingInterceptorRegistrar
                //----> AuditingInterceptor
                //----->IAuditingManager--->AuditingManager（管理IAuditLogSaveHandle ）
                //----->IAuditLogSaveHandle(保存升级日志)
                //--->AuditingManager
                //--->IAuditingStore--->(审计日志存储)AuditingStore
                //Volo.Abp.Auditing
                //--->IAuditLogRepository-- > EfCoreAuditLogRepository(日志记录到数据库中)
                //Volo.Abp.AuditLogging.Domain Volo.Abp.AuditLogging.EntityFrameworkCore
            }
            #endregion
            //开启审计日志模块
            Configure<AbpAuditingOptions>(options =>
            {
                options.IsEnabled = true;  //启动审计
                options.IsEnabledForGetRequests = true;  //启用记录get请求
            });
        }

        /// <summary>
        /// 配置应用模块表后缀名
        /// </summary>
        private void ConfigurModelProix()
        {
            //配置应用权限模块前缀
            AbpPermissionManagementDbProperties.DbTablePrefix = "YDT_";

            //配置应用身份认证模块前缀
            AbpIdentityDbProperties.DbTablePrefix = "YDT_";

            //配置应用租户模块
            AbpTenantManagementDbProperties.DbTablePrefix = "YDT_";

            ////配置审计日志模块
            AbpAuditLoggingDbProperties.DbTablePrefix = "YDT_";

            //配置应用设置模块
            AbpSettingManagementDbProperties.DbTablePrefix = "YDT_";

            //配置特征模块
            AbpFeatureManagementDbProperties.DbTablePrefix = "YDT_";

            if (!AbpOpenIddictDbProperties.DbTablePrefix.Contains("YDT_"))
            {
                //分布式认证系统
                AbpOpenIddictDbProperties.DbTablePrefix = "YDT_" + AbpOpenIddictDbProperties.DbTablePrefix;
            }
        }

        /// <summary>
        /// 配置本地化
        /// </summary>
        private void ConfigureLocalization()
        {
            //配置本地化 切换语言
            Configure<AbpLocalizationOptions>(options =>
            {
                options.Resources
                       .Add<MyProjectResource>("en")
                       .AddBaseTypes(typeof(AbpValidationResource)) //资源继承
                       .AddVirtualJson("/Localizations/Resources");

                options.DefaultResourceType = typeof(MyProjectResource);

                //配置不同国家的语言
                options.Languages.Add(new LanguageInfo("ar", "ar", "العربية"));
                options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
                options.Languages.Add(new LanguageInfo("en", "en", "English"));
                options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)"));
                options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar"));
                options.Languages.Add(new LanguageInfo("hr", "hr", "Croatian"));
                options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish"));
                options.Languages.Add(new LanguageInfo("fr", "fr", "Français"));
                options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi"));
                options.Languages.Add(new LanguageInfo("it", "it", "Italiano"));
                options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
                options.Languages.Add(new LanguageInfo("ru", "ru", "Русский"));
                options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak"));
                options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
                //options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
                options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
                options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch"));
                options.Languages.Add(new LanguageInfo("es", "es", "Español"));
            });

            ////配置本地化 切换语言
            //Configure<AbpExceptionLocalizationOptions>(options =>
            //{
            //    options.MapCodeNamespace("YDT_ABPvNext_Projects", typeof(EbusinessResources));
            //});
        }

        /// <summary>
        /// 配置虚拟文件模块
        /// </summary>
        /// <param name="context"></param>
        private void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
        {
            var hostingEnvironment = context.Services.GetHostingEnvironment();

            //if (hostingEnvironment.IsDevelopment())
            //{
            //配置虚拟文件系统
            //获取项目钟所有文件，包括嵌套文件
            var w = AppDomain.CurrentDomain.BaseDirectory;
            var x = hostingEnvironment.ContentRootPath;
            //Console.WriteLine("12312312312" + x);
            Configure<AbpVirtualFileSystemOptions>(options =>
            {
                options.FileSets.AddEmbedded<HostMoudule>();
                options.FileSets.ReplaceEmbeddedByPhysical<HostMoudule>(x);

                //var data = Path.Combine(hostingEnvironment.ContentRootPath,
                //                 $"..{Path.DirectorySeparatorChar}Ebusiness_Domain");
                //var x = Path.DirectorySeparatorChar;

                //配置领域层虚拟文件系统
                options.FileSets.ReplaceEmbeddedByPhysical<DomainMoudule>(
                            Path.Combine(hostingEnvironment.ContentRootPath,
                                 $"..{Path.DirectorySeparatorChar}Ebusiness_Domain"));

                //options.FileSets.ReplaceEmbeddedByPhysical<EmbeddedResourcesMoudule>(
                //Path.Combine(hostingEnvironment.ContentRootPath,
                //     $"..{Path.DirectorySeparatorChar}EmbeddedResources_Test"));
            });
            //}
        }
    }
}
